package org.refresh.core.conf;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.gems.designer.css.parser.Attributes;
import org.gems.designer.css.parser.CSSParser;

/*******************************************************************************
 * Copyright (c) 2005 Jules White. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors: Jules White - initial API and implementation
 ******************************************************************************/
public class ProblemParser {
	
	public class UnknownDirectiveException extends RuntimeException {
		public UnknownDirectiveException(String msg){
			super(msg);
		}
	}
	
	private Map<String, ConfigDirectiveHandler> handlers_ = new HashMap<String, ConfigDirectiveHandler>();

	public ProblemParser(){
		handlers_.put("Set",new SetVariableHandler());
		handlers_.put("Requires",new RequiresHandler());
		handlers_.put("Required",new RequiredHandler());
		handlers_.put("Excludes",new ExcludesHandler());
		handlers_.put("Select",new SelectHandler());
		handlers_.put("Define",new DefineHandler());
		handlers_.put("Instances",new InstancesHandler());
		handlers_.put("Goal",new GoalHandler());
		handlers_.put("Target",new TargetRequirementHandler());
	}
	
	public RefreshProblem parseProblem(String def){
		RefreshProblem problem = new RefreshProblem();
		
		List<Attributes> attrs = CSSParser.parseAttributes(def);
		for(Attributes attrset : attrs){
			configureFeatureRules(problem, attrset);
		}
		return problem;
	}
	
	public void configureFeatureRules(RefreshProblem problem, Attributes featureconf){
		String context = featureconf.getSelector().trim();
		for(Object key : featureconf.keySet()){
			String directive = ""+key;
			ConfigDirectiveHandler handler = getHandler(directive);
			if(handler == null)
				throw new UnknownDirectiveException("The configuration directive \""+directive+"\" in context \""+context+"\"is not defined.");
			handler.handle(problem, context, directive, featureconf.getProperty(directive));
		}
	}
	
	public ConfigDirectiveHandler getHandler(String directive){
		return handlers_.get(directive);
	}
}
